////////////////////////////////////////////////////////////////////////////////
/// Midnight Circus 2007
////////////////////////////////////////////////////////////////////////////////

namespace GatherTogether
{
    public partial class GatherTogether : System.Windows.Forms.Form
    {
        private string mDefaultFileExtension = "lua";
        private string mFileFilter = "Lua files (*.lua)|*.lua|All files(*.*)|*.*";

        public GatherTogether()
        {
            InitializeComponent();

            ValidateForm();
        }

        private void mMenuItemExit_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void mMenuItemAbout_Click(object sender, System.EventArgs e)
        {
            AboutBox about = new AboutBox();
            about.Show();
        }

        private void mButtonAdd_Click(object sender, System.EventArgs e)
        {
            System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
            dialog.CheckFileExists = true;
            dialog.DefaultExt = mDefaultFileExtension;
            dialog.Filter = mFileFilter;

            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (!mListBoxDatabases.Items.Contains(dialog.FileName))
                {
                    mListBoxDatabases.Items.Add(dialog.FileName);
                }
            }

            ValidateForm();
        }

        private void mButtonRemove_Click(object sender, System.EventArgs e)
        {
            int index = mListBoxDatabases.SelectedIndex;

            if (index != -1)
            {
                mListBoxDatabases.Items.RemoveAt(index);
                mListBoxDatabases.SelectedIndex = System.Math.Min( index, mListBoxDatabases.Items.Count - 1 );
            }

            ValidateForm();
        }

        private void mButtonClear_Click(object sender, System.EventArgs e)
        {
            mListBoxDatabases.Items.Clear();

            ValidateForm();
        }

        private void mListBoxDatabases_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
        {
            // temporarily disable this event or else we will blow the stack
            this.mListBoxDatabases.ItemCheck -= new System.Windows.Forms.ItemCheckEventHandler(this.mListBoxDatabases_ItemCheck);

            // first we need to go through the list and uncheck everything that is currently checked
            foreach (int index in mListBoxDatabases.CheckedIndices)
            {
                mListBoxDatabases.SetItemChecked(index, false);
            }

            // workaround: this event happens before the actual item is checked so if we validate our form below,
            // nothing will be checked and the status label will be misleading and indicate there is no master
            // database selected when there is.
            mListBoxDatabases.SetItemChecked(e.Index, e.NewValue == System.Windows.Forms.CheckState.Checked);

            // reenable this event
            this.mListBoxDatabases.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.mListBoxDatabases_ItemCheck);

            ValidateForm();
        }

        private void mButtonOutput_Click(object sender, System.EventArgs e)
        {
            System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.DefaultExt = mDefaultFileExtension;
            dialog.Filter = mFileFilter;

            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                mTextBoxOutput.Text = dialog.FileName;
            }

            ValidateForm();
        }

        private void MergeButton_Click(object sender, System.EventArgs e)
        {
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;

            try
            {
                // determine the master database file
                string masterDBFile = mListBoxDatabases.CheckedItems[0] as string;

                // parse the master database
                GatherDB masterDB = new GatherDB();
                Parser masterParser = new Parser();
                masterParser.Parse(masterDBFile, masterDB);

                foreach (string filename in mListBoxDatabases.Items)
                {
                    // skip the masterDB file
                    if (filename == masterDBFile)
                    {
                        continue;
                    }

                    // parse the other database
                    GatherDB otherDB = new GatherDB();
                    Parser otherParser = new Parser();
                    otherParser.Parse(filename, otherDB);

                    // merge the other database into the master database
                    Merger.Merge(masterDB, otherDB);
                }

                // dump the master database
                Dumper.Dump(mTextBoxOutput.Text, masterDB);
            }
            catch (ParserException error)
            {
                System.Windows.Forms.MessageBox.Show("Parser Exception!\n\n" + error.Message);
            }
            catch (MergerException error)
            {
                System.Windows.Forms.MessageBox.Show("Merger Exception!\n\n" + error.Message);
            }
            catch (DumperException error)
            {
                System.Windows.Forms.MessageBox.Show("Dumper Exception!\n\n" + error.Message);
            }
            catch (System.Exception exception)
            {
                System.Windows.Forms.MessageBox.Show("Unhandled Exception!\n\n" + exception.Message);
            }

            this.Cursor = System.Windows.Forms.Cursors.Default;
        }

        private void ValidateForm()
        {
            bool ok = true;
            mStatusLabel.Text = string.Empty;

            try
            {
                // ensure that the list contains at least two databases
                if (mListBoxDatabases.Items.Count < 2)
                {
                    throw new System.Exception("Not enough databases specified. Please add at least two databases for merger.");
                }

                // ensure that the list contains a checked database (to use as the master)
                if (mListBoxDatabases.CheckedIndices.Count == 0)
                {
                    throw new System.Exception("No master database specified. Please indicate which database to use as the master.");
                }

                // sanity check
                System.Diagnostics.Debug.Assert(mListBoxDatabases.CheckedIndices.Count == 1);

                // ensure that an output file has been specified
                if (mTextBoxOutput.Text == string.Empty)
                {
                    throw new System.Exception("No output file specified. Please indicate the output path for the merged database.");
                }
            }
            catch ( System.Exception exception )
            {
                ok = false;
                mStatusLabel.Text = exception.Message;
            }

            mMergeButton.Enabled = ok;
        }
    }
}